/** Fichier définissant un objet donné par un potentiel en @f$ r^2 @f$.
 *
 * Ce fichier contient la définition de la classe MetaBalle.
 *
 * @file MetaBalle.hpp
 * @author Johan "Solo" Luisier
 * @date 27 Février 2013
 */
#ifndef METABALLE_HPP
#define METABALLE_HPP

#include "Equipotentielle.hpp"

#include <vector>

/** Classe qui implémente un objet lisse donné par un potentiel en @f$ r^2 @f$.
 *
 * Cette classe implémente un objet lisse dont l'équation est une
 * équipotentielle pour un potientiel tronqué en @f$ r^2 @f$.
 *
 * Implémenté à partir de la description donnée sur le site
 * http://paulbourke.net/geometry/implicitsurf/.
 *
 * @author Johan "Solo" Luisier
 * @date 27 Février 2013
 *
 * @class MetaBalle "MetaBalle.hpp" "Formes/MetaBalle.hpp"
 */
class MetaBalle : public Equipotentielle
{
public:
    MetaBalle( const std::vector< Coord >& poles,
               const Vecteur& xPrime = Vecteur( 1., 0., 0. ),
               const Vecteur& yPrime = Vecteur( 0., 1., 0. ),
               const double& portee = 3.,
               const double& echelle = 1. );
    virtual ~MetaBalle();
    Coord trouveIntersection( const Rayon& ray ) const;
    VecteurU normale(Coord const &pt) const;
    bool estDans(Coord const &pt) const;
    bool estSur(Coord const &pt) const;
    void mapping(const Coord &, int &i, int &j, const int &frequence, const int &Hauteur, const int &Largeur) const;
    std::ostream& affiche( std::ostream& os ) const;
    Coord intrinseque( const Coord& ) const;
    const double& longueurInteraction() const;
    const double& facteurEchelle() const;
protected:
    /** Longueur d'interaction, distance à partir de laquelle le potentiel
     * devient nul.
     */
    double LongueurInteraction;
    /** Facteur d'échelle, permet de moduler la taille du volume.
     */
    double FacteurEchelle;
    /**
     */
    std::vector< Coord > Poles;
private:
    /** Méthode qui définit le potentiel de l'interaction.
     *
     * Cette méthode définit la forme du volume.
     *
     * @param[in] pt point pour lequel on veut évaluer le potentiel.
     *
     * @return la valeur du potentiel au point @c pt.
     */
    double potentiel( const Coord& pt ) const;
};

#endif // METABALLE_HPP
